%Copyright: C.G. van der Laan, cgl@rc.service.rug.nl, 05941-1525 %Version November 1994 \input blue.fmt %\tolerance500\hbadness=499\hfuzz=5pt \title{BLUe's Index} \subtitle{---The principle, and some more\footnote* {BLUe stands for Mr. BLUe---my innocent user and relative of Ben Lee User of the \TeX book fame.}} \issue{MAPS 95.1} \keywords{Compatible extension, education, index, macro writing, number ranges, one-pass job, ordering table, plain \TeX, reusable software parts, software engineering, sort keys. \abstract{The creation of a modest index within a one-pass \TeX{} job is proposed. In general a proof run and a final run are needed.} \contents{Introduction \quad The process and files involved \quad Why? \quad Disclaimer \quad Notations and definitions Example of use: From the \TeX book Example of use: Accents and the like Index Reminders \quad Syntax \quad Markup \quad Examples of IR markup \qquad Spaces \quad Writing IRs Sort and compress: \cs{sortindex} \quad Storing in an array \quad Sorting \qquad Ordering \qquad Ordering table \qquad To be ignored tokens \quad Reduction of entries \quad Transformation index.srt$\rightarrow$index.elm Typeset: \cs{pasteupindex} \quad Running headlines Customization \quad Adding tokens to be ignored \quad Modifying ordering \quad Enriching the index \quad Typesetting the enriched file Tests Robustness Availability, and what is needed from manmac Looking backward Looking forward \quad Subsidiary entries \quad Sorting keys Acknowledgements, Conclusion, References Appendix A: Data: IRs from \TeX book chapter 1-6 Appendix B: Index Appendix C: The index macros. \thisreferences{\TB{} and \LaTeX{} user's guide are omni-present and not explicitly listed.} \references{\chenp\dolwc \laancgh\laancgm\laancgv\makeindex\salomonda\salomondg} %\loadallpictures %\pictures{\indmodelpic} \catcode`\^=7 {\catcode`\^=7 \obeylines \gdef\verbatimgobble#1^^M{}} \beginscript \head{Introduction} Making an index is an art. The fundamental problem is \beginquote What to include in the index? \endquote \noindent Computer-assisted indexing is not simple either. Issues are \bitem the markup of keywords or phrases \bitem to associate page numbers \bitem to sort and compress raw Index Reminders (IRs), and \bitem to typeset the result. \smallbreak\noindent The latter opens the Pandorra box of markup and layout, which prompts for a two-pass job. Up till now the sorting is done outside of \TeX.\ftn{The index for the \TeX book was done by a multi-pass job. In proofmode the raw IRs are written to the file index, and in the final run the enriched file of index entries is encluded in the script, preceded by special markup definitions.} However, producing a modest index in a one-pass \TeX{} job is possible. In `Sorting in BLUe,' I already touched upon the issue of sorting IRs. \noindent I'll build upon manmac's \bitem syntax and types of Index Reminders (IRs) \bitem writing to a file \bitem associating page numbers, and \bitem the formatting in two-columns. \subhead{The process and files involved.} Manmac stores the raw IRs in the file index. I read the file index\ftn{Default index is the value of the toks variable \cs{irfile}, which is used in \cs{sortindex}.} into an array for internal sorting. After sorting I reduce the entries\ftn{Those which differ by page number are collected into one entry.} and write the result to the file index.srt. Then, I transform index.srt into the file index.elm.\ftn{ Default index.elm is the value of the toks variable \cs{indexfile}, which is used in \cs{pasteupindex}. The transformation abandons the IR syntax. The part which specifies the kind of IR is deleted and the word part marked up accordingly.} The result is typeset via \cs{pasteupindex}. \subhead{Schematically} it comes down to \bigskip $$\vcenter{%\indmodelpic \unitlength=6ex \xdim{7.5}\ydim{4} \beginpicture \put(2,0){\makebox(0,0){Result}} \put(2,1){\vector(0,-1){.8}} \put(2,1.25){\makebox(0,0){\cs{pasteupindex}}} \put(5.5,1.6){\vector(-1,0){3}} \put(2,3){\vector(0,-1){1.5}} \put(2,3.25){\makebox(0,0){\cs{sortindex}}} \put(2.5,2.9){\line(1,0){3}} \put(5.5, 2.9){\vector(0,-1){.5}} \put(5.5, 2.25){\makebox(0,0){`Enrich' index.elm\ }} \put(5.5, 2){\line(0,-1){.4}} \put(2,4.3){\vector(0,-1){.8}} \put(2,4.5){\makebox(0,0){Copy + IR markup}} \endpicture \subhead{Why?} For a professional index I agree with Knuth that one can better sort and otherwise enrich the index outside of \TeX. This obeys the separation of concerns principle. However, there is nothing against it to provide macros for producing modest indexes completely within \TeX. Objections\ftn{If any :-).} will faint away hopefully, because of the possibility to {\it enrich the sorted and compressed index (file) outside of \TeX.} The latter is a step beyond manmac. There the raw IRs are written to the file index, while here the sorted and compressed IRs can be worked upon. My work is a compatible extension of manmac, meaning that one can also start from the raw IRs, if one wishes. A side-effect is that the power of \TeX{} for practical problems is demonstrated. \subhead{Disclaimer.} The macros are not foolproof. Don't use as part of the IR \bitem \TeX's special symbols \bitem symbols with special catcodes, for example active symbols like the circumflex \char94, or the tilde \char126 \bitem as part of the IR a control sequence which is not accounted for.\ftn{In the section Looking forward I'll explain how a user can allow for control sequences as part of the IR markup.} \smallbreak \subhead{Notations and definitions.} manmac.tex stands for the macros used by Knuth for formatting his Computers and Typesetting series of books, especially the \TeX book and the \MF{} book. Index reminders denote the markup of script words, to be included in the index. IRs is an abbreviation for Index Reminders. \cs{ea}, \cs{nx} denote \cs{expandafter} and \cs{noexpand}. OTR stands for output routine. FIFO stands for First In First Out, as described in `FIFO and LIFO sing the BLUes.' SiB denotes my `Sorting in BLUe' work. \head{Example of use: From the \TeX book} Let us take for this example some IRs from the first chapter of the \TeX book. I took only part of it and introduced \cs{newpage} now and then to enforce pages with zero, one or more IRs. I used blue.fmt (with manmac embedded). \thisverbatim{\catcode`\|=12 } \beginverbatim %Text from first chapter TeX book Hence the name \TeX, which is an uppercase form of $\tau\epsilon\chi$. ^^{TeX, meaning of}%modified ^^|\tau|^^|\epsilon|^^|\chi| \newpage%no IRs next Insiders pronounce the $\chi$ of \TeX\ as a Greek chi, not as an `x', so that \TeX\ rhymes with the word blecchhh. \newpage%three IRs next In fact, ^{TEX} (pronounced {\sl tecks\/}) is the admirable {\sl Text EXecutive\/} processor developed by^{Honeywell HIS}. Since these two system names are ^^{Bemer, Robert} pronounced quite differently, they should also be spelled differently. \newpage%one IR next The correct way to refer to \TeX\ in a computer file, or when using some other medium that doesn't allow lowering of the `E', is to type `^|TeX|'. Then there will be no confusion with similar names, and people will be primed to pronounce everything properly. \sortindex \pasteupindex !endverbatim \noindent which yields as raw IRs (in file index) \thisverbatim{\catcode`\*=0 \catcode`\!=12 } \beginverbatim TeX, meaning of !0 1. tau !2 1. epsilon !2 1. chi !2 1. TEX !0 3. Honeywell HIS !0 3. Bemer, Robert !0 3. TeX !1 4. *endverbatim \noindent and as index (in file index.elm) \bigbreak\noindent{\bf Index} \medskip\noindent \line{\vbox{\noindent\hsize.5\hsize \noindent {Bemer, Robert}{} 3. \noindent {\tt \char 92\hbox {chi}}{} 1. \noindent {\tt \char 92\hbox {epsilon}}{} 1. \noindent {Honeywell HIS}{} 3. }\vbox{\noindent\hsize.5\hsize \noindent {\tt \char 92\hbox {tau}}{} 1. \noindent {TEX}{} 3. \noindent {\tt TeX}{} 4. \noindent {TeX, meaning of}{} 1. }\hss} \head{Example of use: Accents and the like} I'll show how to mark up Knuth's four types of IRs and how to mark up accents, font switching, and spaces as part of the IR. The last IR markup shows that the representation of page numbers as a range comes out automatically too. \thisverbatim{\catcode`\|=12 \catcode`!=12 \catcode`\*=0 } \beginverbatim Types of IR 0 ^{return} 1 ^|verbatim| 2 ^|\controlsequence| 3 ^\ Accents in IR markup ^{\'el\`eve!}, font changing in IR markup ^{\bf bold} and spaces in IR markup ^{control\ symbol} Control sequences ^{\TeX, and \AmSTeX} ^{Lamport and \LaTeX} brackets ^{\tt< \rm and \tt>} \newpage range representation ^{return} \newpage ^{return} \sortindex \pasteupindex *endverbatim \noindent The above yields in file index as raw IRs \thisverbatim{\catcode`\*=0 \catcode`\!=12 } \beginverbatim return !0 1. verbatim !1 1. controlsequence !2 1. syntactic quantity !3 1. \'el\`eve! !0 1. \bf{}bold !0 1. control\ symbol !0 1. \TeX, and \AmSTeX{} !0 1. Lamport and \LaTeX{} !0 1. \tt{}< \rm{}and \tt{}> !0 1. return !0 2. return !0 3. *endverbatim \noindent and in file index.elm as index \bigbreak\noindent{\bf Index} \medskip\noindent \line{\vbox{\noindent\hsize.5\hsize \noindent {\tt {}< \rm {}and \tt {}>}{} 1. \noindent {\bf {}bold}{} 1. \noindent {control\ symbol}{} 1. \noindent {\tt \char 92\hbox {controlsequence}}{} 1. \noindent {\'el\`eve!}{} 1. }\vbox{\noindent\hsize.5\hsize \noindent {Lamport and \LaTeX{}} 1. \noindent {\TeX, and \AmSTeX{}} 1. \noindent {return}{} 1--3. \noindent $\langle \hbox {syntactic quantity}\rangle ${} 1. \noindent {\tt verbatim}{} 1. }\hss} \head{Index Reminders} IRs are at the heart of the process. Knuth distinguished 4 types to facilitate the outside processing. I'll adopt his IRs syntax and types. \subhead{Syntax.} Knuth's IRs obey the syntax\ftn{In contrast with my previous given syntax it seems that Knuth was less restrictive. Earlier I overlooked that the entries are ended by a period.} \thisverbatim{\emc} \beginverbatim !]!!!]. !endverbatim The digits 0, 1, 2, or 3 denote the types: words, verbatim words, control sequence, and syntactic quantity. A user does not have to bother about the digits, nor about the page numbers. Knuth has adopted the accompanying conventions for the word(s) of IRs.\ftn{See \TB, p424 for the IR types, and what is typeset in the result. In \cs{vref} the markup is inserted as replacement text of \cs{next}. What is set in the index is governed by the macros which are included after \cs{begindoublecolumns} in the \TeX book script.} $$\vbox{\offinterlineskip\def\tstrut{\vrule height2.5ex depth.5ex width0pt} \halign{\tstrut#\hfill\quad\vrule\quad&#\hfill\quad\vrule\quad&#\hfill\cr Mark up&Typeset in copy$^*$&IR \cr \noalign{\hrule} |^{...}| &\dots &|... !!0 |$\langle page\, no\rangle$.\cr |^!vrt...!vrt| &|!vrt...!vrt|& |... !!1 |$\langle page\, no\rangle$.\cr |^!vrt\...!vrt| &|!vrt\...!vrt| & |... !!2 |$\langle page\, no\rangle$.\cr |^\<...>|&$\langle\dots\rangle^{**}$& |... !!3 |$\langle page\, no\rangle$.\cr \noalign{\vskip.5ex\hrule width1cm\relax\vskip1ex} \multispan3{\quad$^*\,$\vrt\dots\vrt\ denotes manmac's, TUGboat's,\dots verbatim. \hfil}\cr \multispan3{\quad$^{**}\,$in \cs{rm}. \hfil}\cr For the user the word(s) are important. The allowed markup for the IRs and the result in the copy are given in the accompanying table. \subhead{Markup.} The markup for IRs is near to natural. Precede the entry by a circumflex (or two circumflex(es) in case of a silent index entry).\ftn{Silent IRs mean that these will appear only in the index, not on the page.} \example{IR markup.} \thisverbatim{\catcode`\|=12 \catcode`\^=12 \catcode`!=12 \catcode`*=0 } \beginverbatim ^{text, e.g. \'el\`eve!} ^|verbatim text| ^|\controlsequence| ^\ %and for silent ones, double the ^ ^^\ %from the TeX book {\sl^{ligatures}} |'$|^|\,||$''| ^^{markup commands, see control sequences} %from Looking forward section ^{Lamport and \LaTeX} *endverbatim \subsubhead{Spaces} are as always difficult. In the IR they separate parts of the IR, and are used in the word part. Just typing a space has as effect that it will be neglected during sorting. The markup `\cs{\char32}', a control space, will yield a space subject to sorting, according to the ordering table. \cs{space} markup will be neglected during sorting. This token is default member of the set of to be ignored control sequences. It will be set in the index as \cs{\char32}. \example{Spaces} The following markup \thisverbatim{\catcode`\|=12 } \beginverbatim Spaces test ^{\space}%an ignored cs ^{a\ a} %control space ^{aa} ^{a\ b} ^{a \TeX} ^{a\ \bf a} ^{\TeX book} ^{xyz beta}%negelected in sorting ^{xyza} ^|\space| \sortindex \pasteupindex !endverbatim \noindent yields as file index \thisverbatim{\catcode`\!=12 \catcode`\;=0 } \beginverbatim \space {} !0 1. a\ a{} !0 1. aa{} !0 1. a\ b{} !0 1. a \TeX {} !0 1. a\ \bf a{} !0 1. \TeX book{} !0 1. xyz beta{} !0 1. xyza{} !0 1. space{} !2 1. ;endverbatim \noindent and as file index.srt \thisverbatim{\catcode`\!=12 \catcode`\;=0 } \beginverbatim \space {} !0 1. a\ \bf a{} !0 1. a\ a{} !0 1. a\ b{} !0 1. aa{} !0 1. a \TeX {} !0 1. space{} !2 1. \TeX book{} !0 1. xyza{} !0 1. xyz beta{} !0 1. ;endverbatim Explanation. \cs{space} belongs to the set of to be ignored control sequences, ICSs for short. This means that it is skipped with respect to sorting, except when it occurs as the last token of the word part. In that case they are ordered as a space, that is according to the lowest value. This explains the position of `\cs{space}.' `\cs{TeX},' and `\cs{TeX} book,' are subject to the default sort keys. `xyza' precedes `xyz beta,' because the space is silent. When word ordering is preferred a \cs{\char32}, a control space, must be included. \subhead{Writing the IRs in index.} This comes with manmac. The writing is done in two phases: first while processing the script, and second in the OTR where the page numbers are attached. The (manmac) macro which does the first part of the writing is \thisverbatim{\catcode`\~=0 \catcode`\!=12 } \beginverbatim \def\makexref{\ifproofmode \bgroup\def\ {\string\ }% \xdef\writeit{\write\inx{\text{} !\xreftype\space \nx\number\pageno.}}\writeit \egroup \else\ifhmode\kern0pt\fi\fi \ifsilent\ignorespaces\else\next\fi} ~endverbatim I don't write in the margin. In Appendix C the full-BLUe macro has been provided. Font changing control sequences, accents and \cs{space} are written as a `string' in the file index. Actually, I introduced also the sorting on sorting keys. Because of the different use of \cs{space} I introduced \cs{spaceseparator}. \head{Sort and compress: \cs{sortindex}} The functionality of \cs{sortindex} is to transform the file of raw index reminders---index---into the file with sorted and compressed index entries---index.elm. All we have to do is to \bitem write the raw IRs in the array, and keep the upper bound of the array in \cs{n}, \bitem sort with the right comparison macro (\cs{cmpir}, and at the lower level for the word part \cs{nxtwindex}), next to the use of the ordering table \cs{otindex} \bitem reduce the index entries by collecting the same entries which differ by page number \bitem write the result to the file index.srt, and transform this into index.elm. \smallbreak \beginverbatim \def\sortindex{%Nov 1994, cgl %Purpose: %To sort IR file. %Input: default index is sorted % ( file specified in \irfile) %Output: file index.elm. \newpage\immediate\closeout\inx \filetoarray{\the\irfile} \immediate\write16{Sorting n=\the\n. Please wait, O(nlog n) process.} \let\cmp\cmpir\let\nxtw\nxtwindex \otindex\let\ \space \sort {\let\spaceseparator\space \setupnxtokens\def\ {\nx\ }% \immediate\write16{Range reduction.} \redrngtofile{index.srt} \immediate\write16{After reduction and writing to file index.srt; n=\the\n.} \immediate\write16{Transform index.srt-->index.elm.} \tawfiletofile{index.srt}{\the \indexfile}}} !endverbatim\noindent with auxiliary \beginverbatim \def\setupnxtokens{% \def\process##1{\def##1{\nx##1}}% \ea\fifo\the\conseqs\ofif \def\process##1{\def##1{\string##1}}% \ea\fifo\the\consyms\ofif !endverbatim\noindent In Appendix C the full-BLUe version has been incorporated. \subhead{Storing in an array.} The storing of data from a file into an array has been treated in SiB. A slightly modified version of the macro reads \beginverbatim \def\filetoarray#1{%#1 is file name \immediate\openin\inxin=#1\relax \ifeof\inxin\immediate\write16{File #1 empty or non-existent.}% \fi \n\kzero\continuetrue \loop\ifeof\inxin\continuefalse\fi \ifcontinue\advance\n1 \immediate \read\inxin t\ea o\csname\the\n\endcsname \repeat\advance\n-1 \immediate\closein\inxin} !endverbatim \subhead{Sorting.} For sorting I make use of my macros as released in SiB. Comparison needs a multiple key. This means that at the outer level we have to supply \cs{cmpir}\ftn{Mnemonics compare index reminder.} and at the lower level have to compare words, and digits. The words are handled by \cs{nxtwindex} and the numbers are compared via an \cs{ifnum}. The comparison macro for IRs reads \thisverbatim{\unmc} \beginverbatim \def\cmpir#1#2{%#1, #2 defs %Result: \status= 0, 1, 2 if % \val{#1} =, >, < \val{#2} \ea\ea\ea\decom\ea#1#2} !endverbatim The crucial macro for comparison of the word part of the IR reads \beginverbatim \def\nxtwindex#1#2{% %Function: %On input: #1 contains the `word' %As result: #2 contains the value % of the first non-ignored token as given % in the ordering table. %#1 contains the rest of the `word' \def\pop##1##2\pop{% \gdef#1{##2}\def\pophead{##1}}%head and tail \ea\pop#1\pop%split in head and tail \ignores\ea\ea\ea{\ea\the\ea\conseqs \the\consyms}% \ea\loc\pophead{\the\ignores}% \iffound\ifx\empty#1 \chardef#2=0 \else\nxtwindex#1#2\fi \else \ea\let\ea#2\csname ot\pophead\endcsname\fi %with toks variables \conseq{\c\space\bf\it\rm\tt\TeX\sub} \consyms{\`\'\"\^\~} !endverbatim The idea is to process the `word' argument by argument.\ftn{Not token by token, beware!} However, some tokens are not relevant for the ordering and have to be ignored. This is done by collecting all tokens to be ignored in the toks variable \cs{ignores}, and compare \cs{pophead} with this string. The above can be extended to control sequences to be sorted on separately provided sorting keys. See the Looking forward section. For \cs{decom} and other low level macros related to sorting within \TeX{} see `BLUe's Format,' or `Sorting in BLUe.' In Appendix C the full-BLUe versions have been incorporated. \subsubhead{Ordering.} A fundamental issue with indexes is the ordering. The ASCII table is not suited because lowercase and uppercase letters differ by 32. I decided to rank these as equal, more precisely to assign the lowercase ASCII values to both. I prefer from the following the left column above the right one \beginverbatim el el El!`eve em em El!`eve !endverbatim Moreover, accented letters are not part of ASCII. How should we order for example e, \'e, \`e, \^e, \"e? I decided to rank accented letters equal to those without an accent, because I prefer from the following the left column above the right one \beginverbatim el el !leavevmode!'el!`eve em em !'el!`eve !endverbatim I know that non-letters precede letters but what about there relative ordering? I decided to stay as close as possible to the ASCII ordering. Then there is the problem of digits. In IRs they come as part of the word(s) and as page numbers. For the latter I used the numerical ordering. For the former I used the alphabetical ordering.\ftn{I could have applied a look ahead mechanism and use numerical ordering throughout. Maybe another time.} Furthermore, a user can select the so-called `word ordering,'\ftn{This means that spaces precedes all letters. A space as such is neglected in the ordering.} by \cs{\char32}, \TeX nically a control space, as markup for a space. Personally, I like from the following the first column better than the second \beginverbatim sea lion seal seal sea lion !endverbatim \subsubhead{Ordering table.} This ordering `table' is simpler than the one released in SiB, because accents have been ignored. Furthermore, I adhere mostly to the ASCII ordering, as can be seen easily. \thisverbatim{\catcode`\|=12 \catcode`\!=12 \catcode`\~=0 } \beginverbatim \def\otindex{%Parameters: Ordering `table' %Special cases \ea\chardef\csname ot \endcsname=0 \ea\chardef\csname ot\space\endcsname=0 %{|}~char126 come in ASCII after lowercase %^ is active character %Bulk according to ASCII \def\process##1{\ea\chardef \csname ot##1\endcsname=`##1 } %lowercase letters \fifo abcdefghijklmnopqrstuvwxyz\ofif \chardef\otij=`y \chardef\otIJ=`y %other characters} \fifo!"##$&'()*+,-./0123456789:;<=>?@ []_`\ofif %assign lowercase values to uppercase letters \def\process##1{\ea\chardef \csname ot##1\endcsname=\lccode`##1 } \uppercase{\fifo abcdefghijklmnopqrstuvwxyz\ofif} ~endverbatim Attention needs \TeX's specials, in particular the escape character \cs{}, the circumflex \char94, and the percent \%. \subsubhead{To be ignored tokens.} In practice I needed things like \cs{tt} as part of the IR, which must be neglected while sorting.\ftn{The reason is that {\tt <, and >} are used and then printed wrongly.} I decided to ignore those tokens while sorting and to include the tokens in the final index.elm as such. Another realistic approach is to add this kind of markup later in the file index.elm. \subhead{Reduction of entries.} The functionality is that the IRs which differ by page number are collected into one entry with the page numbers represented efficiently, for example in ranges. The macros from SiB have the functionality \beginverbatim \def\redrngtofile#1{%Reduction of \1...\n, %with range representation of page numbers. %The result is written to file #1. \def\prcrng#1{%Prints the numbers so far if %the new number differs more than 1 from the %last. If the difference is 1 the range is %extended. \def\strnrs{%Accumulates numbers in \nrsrng. %either as a range or as such. %\frst stands for first number %and \lst for last number. If they equal the %number is stored, if they differ by 1 both %the numbers are stored separated by \sepn, %and if they differ by more than 1 %\frst--\lst is stored. !endverbatim For the first macro see Appendix C. The other two have been released already as part of blue.fmt and are unaltered. \subhead{Transformation index.srt$\rightarrow$index.elm.} When we inspect the copy for the index in the \TeX book file then we'll find that the entries of the enriched file don't obey the syntax of the IRs. The part with !$\langle digit\rangle$ has disappeared. Pondering about this made me agree with Knuth, as usual.\ftn{I noticed furthermore, that some IRs did not make it into the final index. Apparently, given the other IRs, he decided to delete less relevant ones.} It is no longer functional! The file can better be considered as copy as such, to be processed in the final run. Because of this I transformed index.srt, the file of sorted and compressed IRs, into the file index.elm, with the coding !$\langle digit\rangle$ absorbed as markup in the word part. \beginverbatim \def\tawfiletofile#1#2{% #1 from file \continuetrue % #2 to file \immediate\openin\inxin=#1\relax \immediate\openout\inx=#2\relax \loop\read\inxin to\IR \ifeof\inxin\continuefalse\fi \ifcontinue\trfandwrite\IR \repeat \immediate\closein\inxin \immediate\closeout\inx %with auxiliaries \newread\inxin\newwrite\inx\newtoks\indword \def\splitintoks#1 !#2 #3.{\indword{#1}% \chardef\digit=#2\relax\def\pagenrs{#3}} \def\trfandwrite#1{\ea\splitintoks#1% \immediate\write\inx{\nx\noindent \ifcase\digit{\the\indword}\or {\nx\tt\the\indword}\or {\nx\tt\char92\hbox{\the\indword}}\or $\nx\langle\hbox{\the\indword}\nx\rangle $\fi\spaceseparator\pagenrs.}} !endverbatim \subsubhead{Explanation.} In \cs{trfandwrite} I used the toks variable for storing the word part, because when writing it comes out handy that \cs{the} is a one-step expansion. Note that \cs{trfandwrite} takes care of the markup for \cs{pasteupindex}. The \cs{noindent} is inserted to enforce horizontal mode, especially in presence of accents at the beginning of the word. In \cs{tawfiletofile} the test for the end of file looks peculiar.\ftn{Remember that \TeX{} appends a \cs{par} to the input file.} \head{Typeset: \cs{pasteupindex}} In the \TeX book the typesetting of the enriched index entries is treated on p261--264. Let us start from there and distill our specifications. The typesetting of main and subsidiary entries is discussed given the file of index entries. This is intertwinned with the page break mechanism in relation to what should appear in the running headlines. My specifications for typesetting the index are \bitem represent the four IR types the same as in the \TeX book \bitem set in two-columns, balanced, possibly preceded by one-column copy \bitem set subsidiary entries analogous to the \TeX book \bitem indent continuation lines by 2em \bitem indent subsidiary entries by 1em \bitem underline page numbers which represent the definition or the main source of information \bitem represent a page number in italics when that page contains an instructive example of the concept in question. \smallbreak\noindent Essentially nothing new. The challenge is how to implement this, such that an index can be handled in a one-pass job. In order not to make things too complex, I'll postpone the handling of subsidiary entries until the Looking forward section. Let us say that this is a feature for the `next release,' of blue.fmt. The enrichements such as representation of numbers in italics or underlined, which have all to do with the wish to direct readers to the main source or to instructive examples, are left to the manual editing of the index.elm file. The reason is---In agreement with Knuth?---that this is difficult to foresee at the time when the IR markup is inserted in the script. Moreover, it complicates the sorting et cetera process. In the mean time users can edit index.elm---read add markup---and provide the necessary macros in for example \cs{preindex}. In short follow Knuth. The compressed and sorted aray of index entries is set via the invocation \cs{pasteupindex}.\ftn{As modification for the pair \cs{begindoublecolumns} and \cs{enddoublecolumns}, because the latter is too much intertwinned with manmac. For an explanation of the underlying macro the reader is referred to the \TeX book p416--417.} The contents of \cs{preindex} and \cs{postindex} are used appropriately. \beginverbatim \def\pasteupindex{%Nov 1994, cgl %Purpose: %To set index in (balanced) doublecolumn. %The index is preceded by contents of %\preindex and followed by contents of %\postindex. %Input: default index.elm is set % (file specified in \indexfile). %Biased by manmac's \begindoublecolumns \newpage\begingroup \def\space{{\tt\char32 }}% \the\preindex\par \pageheight\vsize \pagewidth\pagewd%anachronism \parindent1em \output={\global\setbox\partialpage= \vbox{\unvbox255\bigskip}}% \eject \output={\bluedoublecolumnout}% \hsize=8.5cm \vsize=51cm%blue.fmt values \parskip0pt plus.8pt\relax \obeylines\everypar{% \hangindent2\parindent}% \let\par\endgraf \let\sub\endgraf \input\the\indexfile\relax %endpasteupindex part biased by %manmac's \enddoublecolumns \output={\balancecolumns}\eject \endgroup \pagegoal=\vsize\the\postindex %auxiliaries adapted from manmac \def\bluedoublecolumnout{% %Biased by manmac's doublecolumnout \splittopskip=\topskip \splitmaxdepth=\maxdepth \dimen@=25cm \advance\dimen@ by-\ht\partialpage \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@ \blueonepageout\pagesofar \unvbox255 \penalty\outputpenalty} \def\blueonepageout#1{% %Biased by manmac's \onepageout \shipout\vbox{% \vbox to\baselineskip{\null \the\headline\vss}% \kern2ex \vbox to\pageheight{#1}% \kern1ex \the\footline }\advancepageno} !endverbatim The file name is parameterized in a token variable \cs{indexfile}. Default is |\indexfile{index.elm}|. A user can specify his own file via \thisverbatim{\emc} \beginverbatim \indexfile{} !endverbatim \subhead{Running headlines.} The advanced mechanism of having the top entries and bottom entries appropriately represented in the headline has been treated In the \TeX book. Looking at the indexes of the \TeX book and the more recent Graphbase book, I noticed that Knuth did not use it. In Appendix D he states that the index is not tall enough to justify the mark mechanism. It is really advanced and subtle, and for those who are interested, please peruse the \TeX book. \head{Customization} A user might want to interfere at the places \bitem to include other tokens to be ignored while sorting\ftn{However, in the Looking forward section this has been generalized into the possibility to provide the control sequence with a sorting key.} \bitem to supply an ordering of his own \bitem to enrich the sorted and compressed file index.elm. \smallbreak \subhead{Adding tokens to be ignored.} In general we don't know what control sequences stand for. What are reasonable requirements to impose upon the handling of markup control sequences (cs for short)? In my opinion \bitem the cs must be defined \bitem \cs{makexref} writes the cs unexpanded \bitem ordering? unknown, and therefore neglected\ftn{However, see the Looking forward section, ;-).} \bitem \cs{setupnxtokens} guards that the cs-s are written, unexpanded, to index.srt and index.elm. \smallbreak As a consequence I decided to neglect the `in between' control sequences while sorting. For those who favour a one-pass job, I have provided the following, although it is simpler to add those control sequences to index.elm. The extension of the set of to be ignored tokens can be done via \beginverbatim \add#1to#2 %for example adding to set of control %sequences \add\hfil to\conseqs %or control symbols \add\`to\consyms %Adding to the set of sort key pairs \add\hfil{hfil}to\srtkeypairs !endverbatim Each element from \cs{conseqs} is redefined such that the control sequence token is written to the file with a space appended.\ftn{\cs{noexpand} is used instead of \cs{string}.} \subhead{Modifying ordering.} The most general way is to `copy' the ordering table for modification.\ftn{My \cs{fifo} is just a short cut, which also prevents typos in assigning the ASCII values. For \cs{fifo}, see my `FIFO and LIFO sing the BLUes.'} \subsubhead{And what about a macro to add to the table?} This can be done easily, and superficially looks convenient for an innocent user. At the moment I don't trust the macros to be worthwhile for an innocent user, unless a very modest index has to be made. And this completes the circle: different ordering is not wanted, I guess. \subhead{Enriching the index.} This use is necessary when for example \bitem control sequences have to be typeset \bitem special symbols are needed, or \bitem cross-references within the index are required. \smallbreak\noindent The best way is to start from the index.elm file. An example of use is that in the 4\TeX{} manual the index is sorted on 4TeX, but in the index a different representation is desired. (The control sequence \cs{fourtex} has been used for typesetting instead of 4TeX.) For that purpose the file with IRs contains 4TeX and later this is substituted in the file index.elm by \cs{fourtex}. Another approach is to supply pairs of control sequences and sorting keys. See the Looking forward section. \subhead{Typesetting the enriched file.} When the default name is used---index.elm---just say \cs{pasteupindex}. For another file name assign this name to the toks variable \cs{indexfile}, prior to the invocation of \cs{pasteupindex}. \head{Tests} The macros have been tested on the file which was obtained from the \TeX book chapters 1 to 6. The (slightly adapted) file of raw IRs and the resulting sorted and compressed index entries have been included in the Appendices A and B. The test had to do with some 220 raw IRs. A driver program, which starts from a file of IRs not necessarily generated by manmac, is \beginverbatim \input blue.fmt %\irfile{erik.15b} %file with 6 entries \irfile{erik.16b} %file with 19 entries %\irfile{indexdat.610}%file with 183 entries %\irfile{erik.cgl} %file with 228 entries \sortindex \pasteupindex !endverbatim Another test file was from the 4\TeX{} manual. This makeindex file consisted of roughly 760 entries of the form |\indexentry{...}{}|. I first transformed this file---by \TeX{} :-)))---into a file obeying the IR syntax, via \beginverbatim \newwrite\erik \immediate\openout\erik=erik.cgl \def\indexentry#1#2{% \immediate\write\erik{#1 !!0 #2.}} !endverbatim Then I edited the file in order to \bitem remove the backslash(es) in the middle of the word part \bitem adjust IR type for control sequences (0 into 2) such that the sorting et cetera went smooth. \smallbreak As result I obtained 343 sorted and compressed index entries. For typesetting some back substitutions had to be made \bitem in between backslashes inserted again \bitem the substitution/insertion of special control sequences. \smallbreak The total sorting time on my Mac Classic II was roughly 20 minutes, with 12200 IR comparisons, and 54149 words of memory used.\ftn{A dummy job which just stores the IRs but does not sort nor reduce the number of entries needed 34884 words of memory.} As format I used blue.fmt.\ftn{While proofing this work, it needs less hand work, because the control sequences can be accounted for via sort key pairs. See the Looking forward section.} A final test was about copy with font changes and accents as part of the IRs. This file has been supplied in the second example of this article. \head{Robustness} The weak point in this automated complicated process is the specification of the IRs. When wrong ones are supplied low-level \TeX{} error messages will emerge, and definitely will put off a user. My only remedy to this is \bitem don't hardly use markup within the IR \bitem don't use active charcters as part of the IR \bitem don't use \TeX{} special characters, especially backslashes apart from a single control sequence (a type 2 IR.) \smallbreak\noindent %To locate errors I also print in the log file the number of elements to be sorted: n. This must be greater than zero. When n=0 is printed, the file of raw index entries is apparently empty, and 9 out of the 10 cases the asynchronous behaviour of the OTR is the cause, meaning that the file was already closed before it was written. When the file is empty, as argument of \cs{filetoarray}, a message is delivered in the log file. In the macros I have left some \cs{immediate}\cs{write}s, preceded by \%, which can be used to follow what is compared. This is handy when spotting an out of order IR. \head{Looking backward} It all started with sorting an array in SiB. In the early stage of this paper I adhered the model to allow writing IRs to a file and also, as option, to write directly to the array. Because of the latter, I had to modify the OTR such that the array elements were extended with page numbers. I used the mark mechanism and it worked.\ftn{However there was still a detail to be fixed: the first mark was also written in the main vertical list.} I abandonned this option for simplicity reasons. When restricted to writing to a file a reader does not have to bother about the OTR, and no redefinitions of the array elements are needed. A price I had to pay for flexibility is the generation of the replacement texts for control sequences to be ignored, each time in every invocation of \cs{makexref}. Another `inefficiency' is the `generation' of the ordering table. Perhaps, I should just have included the `tables' as such instead. A final point is the general conflict with control sequences already in use. \head{Looking forward} Is it realistic to expect that there will be another user besides me? I don't think so, because history has it that manmac as such has been neglected at large, and I don't see why people would nevertheless prefer my work, which is so intimately connected to manmac. Whatever the future has in store, let us go on. \subhead{Subsidiary entries.} What are the requirements for this? Let us assume that the markup for a subsidiary entry starts with \cs{sub}. IMHO the following specs are relevant \bitem \cs{sub} should be neglected in the copy \bitem write \cs{sub} as string to the file index \bitem neglect \cs{sub} while sorting \bitem `reduce' entries which differ in subentries by suppressing the main entry except for the first time, while typesetting the index element \bitem indent the subsidiary entry by \cs{parindent} while typesetting. \smallbreak\noindent The above specs can be realized as follows \bitem |\let\sub=\relax| \bitem include \cs{sub} in \cs{conseqs} \bitem the reduce problem is similar to the typesetting of references, where the author part is printed once for different publications. I found that in \AmSTeX, and used it in `BLUe's References.' \bitem add |\let\sub=\endgraf| in \cs{pasteupreferences}. \smallbreak\noindent Actually, the above has been incorporated in blue.fmt. \subhead{Sorting keys.} So far we have mostly neglected tokens while sorting. But, \dots is it do-able to sort each control sequence according to a sorting key? This comes down to \bitem provide a way to specify for sorting key pairs, that is pairs of a control sequence and its sorting key \bitem sort on the sorting key \bitem set the index entries with the embedded control sequences according to their definitions. %\smallbreak \example{Use of sorting keys} Suppose that we have \beginverbatim \add\fourtex{4tex}to\srtkeypairs \add\fourtex to\srtkeys %\setupsrtkeys Copy with ^{IR \fourtex} \sortindex %with 4tex for \fourtex \pasteindex%Set `IR \fourtex{} ' !endverbatim \noindent then the file index will contain the IR \thisverbatim{\catcode`\!=12 \emc \catcode`\;=0 } \beginverbatim IR \fourtex{} !0 ;endverbatim\noindent The above will be sorted on 4tex. The key issue in the implementation is to extend \cs{nxtwindex} by the test \cs{pophead}$\in$ \cs{srtkeys}. If the test yields true sort further on ||, that is insert the sorting key. Actually the above has been included in blue.fmt with as defaults \beginverbatim \conseqs{\c\space\bf\it\rm\tt\sub\relax} \consyms{\`\'\"\^\~} \srtkeypairs{\TeX{tex} \LaTeX{latex} \AmSTeX{amstex}} \srtkeys{\TeX\LaTeX\AmSTeX} !endverbatim\noindent In order to use this nice feature extend the script as follows \beginverbatim \add...to\srtkeypairs%one or more pairs \setupsrtkeys %extends the set of %sort keys ...%copy proper \sortindex \pasteupindex !endverbatim\noindent The last issue of suppressing the main word with multiple sub entries can be implemented too. For the moment I refrained, and will wait for user action. \head{Availability} The macros are released in the public domain as part of blue.fmt, version November 1994. Needed from manmac are the IR macros, |^| and its auxiliaries, next to some macros for handling the doublecolumns, for example \cs{balancecolumns}. Some macros from SiB are used too, especially the sorting macros. An easy way is to include blue.fmt, which contains them all. \head{Acknowledgements} Erik Frambach thank you for the file of 4\TeX, your assitance, and your sound judgement. As usual Jos Winnink helped me again to procruste the markup of the article into maps.sty. \head{Conclusion} The macros work smoothly for a modest and practical index. I intend to use the macros in the near future for my `Publishing with \TeX' booklet. The macros serve an educational purpose, and stimulate thinking. My added value to manmac is, that a modest index can be processed in a one-pass job. More complex indexes can be processed via a proof run, editing of index.elm, and a final run with index.elm inserted as copy. For a foolproof approach it is necessary to look ahead for general tokens. The problem is that we can't account for all the control sequences or active characters to be used. For indexes of modest complexity my limited approach is good enough. The bonus is simplicity throughout. In general it is difficult to know when to stop, as Schumacher in his precious `Small is beautiful' already pointed out. My case rest. \pasteupreferences \newcol \head{Appendix A: File of raw IRs from the \TeX book} \thisverbatim{\catcode`\~=0 \catcode`\!=12 \beginverbatim %Entries with non-monotone page numbers have %been added to enforce range representation. tau !2 1. epsilon !2 1. chi !2 2. chi !2 1. beauty !0 1. logo !0 1. TEX !0 1. Honeywell Information Systems !0 1. Bemer, Robert, see TEX, ASCII !0 1. TeX !1 1. PLATO !0 2. BACON !0 2. quotation marks !0 3. ASCII !0 3. apostrophe !0 3. blank space !0 3. dashes !0 3. hyphens !0 3. minus signs !0 3. En-dash !0 3. En-dash !0 2. Em-dash !0 5. bibliography !0 4. ligatures !0 4. ligatures !0 3. kerning !0 4. dangerous bend !0 4. lq !2 4. rq !2 4. quotes within quotes !0 4. thinspace !2 4. , !2 4. SWIFT !0 5. JEVONS !0 5. escape character !0 6. backslash !0 6. control sequences !0 6. markup commands, see control sequences !0 6. input !2 6. Polya !0 6. Szego !0 6. acute !0 6. umlaut !0 6. ' !0 6. " !0 6. accents !0 6. accents !0 4. accents !0 5. control word !0 6. letter !0 6. control symbol !0 6. space !0 6. * !2 6. !2 7. !2 7. carriage-return, see !0 7. logo !0 7. TeX !2 7. pi !2 7. Pi !2 7. aleph !2 7. infty !2 7. le !2 7. ge !2 7. ne !2 7. oplus !2 7. otimes !2 7. uppercase !0 7. lowercase !0 7. primitive !0 7. input !2 7. ' !2 7. " !2 7. accent !2 7. exercise !2 8. show !2 8. thinspace !2 8. kern !2 8. log file !0 8. SELDEN !0 9. LINCOLN !0 9. typeface !0 10. bold !0 10. fonts !0 10. rm !2 10. sl !2 10. it !2 10. tt !2 10. bf !2 10. typewriter type !0 10. face !0 10. roman type !0 10. oblique !0 10. Slanted type !0 10. italic type !0 10. curly brace !0 10. brace !0 10. grouping !0 10. Dieter !0 10. / !2 10. El\`eve !0 10. punctuation !0 11. nullfont !2 11. points !0 11. dangerous bend !0 11. subscripts !0 11. tenrm !2 11. ninerm !2 11. tensl !2 11. ninesl !2 11. baseline !0 11. tenpoint !2 11. ninepoint !2 11. Computer Modern !0 12. cm fonts !0 12. font !2 12. design size !0 12. at !1 12. magnification !0 12. reduction !0 12. cmr5 !1 12. piano !0 12. magstep !2 12. magstephalf !2 12. magnification !2 12. LEE !0 13. SHAKESPEARE !0 13. grouping characters !0 14. curly braces, see braces !0 14. block structure !0 14. local !0 14. TeX !2 14. space !0 14. empty group !0 14. lbrace rbrace !0 14. ligature !0 14. control space !0 14. centerline !2 14. nested !0 14. global !2 15. page number !0 15. Output routines !0 15. advance !2 15. begingroup !2 15. endgroup !2 15. nested groups !0 15. MUIRHEAD !0 16. HOWARD !0 16. Running the program !0 17. ** !1 17. relax !2 17. return !3 17. asterisk !0 17. end !2 17. [1] !1 17. texput !1 17. dvi !1 17. device independent !0 17. story\period{}tex !1 17. hrule !2 17. vskip !2 17. eject !2 17. rule !0 18. paragraphs !0 18. blank line !0 18. empty line !0 18. umlaut !0 18. cedilla !0 18. ties !0 18. tilde !0 18. vfill !2 18. eject !2 18. file names !0 18. ** !1 18. * !1 18. input !2 18. ampersand !0 18. format file !0 18. preloaded formats !0 18. end !2 19. percent !0 19. comments !0 19. hsize !2 19. input !2 19. overfull box !0 19. [] !1 20. r\'esum\'e{} !0 253. leading, see vskip !0 17. centerline !2 17. Thor !0 17. " !2 17. c !2 17. Drofnats !0 17. vfill !2 17. transcript !0 20. log file !0 20. hyphenation !0 20. discretionary hyphens !0 20. badness !0 20. tolerance !2 21. hbadness !2 21. underfull box !0 21. column width !0 21. measure, see hsize !0 21. raggedright !2 21. breaking a paragraph !0 21. hfuzz !2 21. dash !2 21. error messages !0 21. ? !1 22. italic correction !0 10. inserting text online !0 22. online interaction, see interaction !0 22. interacting with TeX !0 22. deleting tokens !0 22. help messages !0 23. scrollmode !2 23. nonstopmode !2 23. batchmode !2 23. errorstopmode !2 23. interrupt !0 23. argument !0 23. centerline !2 23. editing !0 24. errorcontextlines !2 24. ARISTOTLE !0 25. HABAKKUK !0 25. COWPER !0 25. ~endverbatim \newcol \head{Appendix B: Index} The index below has been typeset via \thisverbatim{\catcode`\!=12 \catcode`\~=0 } \beginverbatim {\obeylines\gdef\typindentry#1 {%#1 an IR as such \if!#1!\expandafter\egroup\else% \splitintoks#1% \ifcase\digit{\the\indword}\or% {\tt\the\indword}\or% {\tt\char92\hbox{\the\indword}}\or% $\langle\hbox{\the\indword}\rangle$\fi{} % \pagenrs.\fi\par} \bgroup\def\par{\endgraf \typindentry} \obeylines ' !0{} 6. ' !2{} 7. ~endverbatim \subhead{Index.} {\obeylines\gdef\typindentry#1 {%#1 a IR \if!#1!\expandafter\egroup\else% \splitintoks#1% \ifcase\digit\the\indword\or% {\tt\the\indword}\or% {\tt\char92\the\indword}\or% $\langle\hbox{\the\indword}\rangle$\fi{} % \pagenrs.\fi\par} \bgroup\def\par{\endgraf \typindentry} \obeylines ' !0{} 6. ' !2{} 7. " !0{} 6. " !2{} 7, 17. * !1{} 18. * !2{} 6. ** !1{} 17, 18. , !2{} 4. [] !1{} 20. [1] !1{} 17. / !2{} 10. ? !1{} 22. accent !2{} 7. accents !0{} 4--6. acute !0{} 6. advance !2{} 15. aleph !2{} 7. ampersand !0{} 18. apostrophe !0{} 3. argument !0{} 23. ARISTOTLE !0{} 25. ASCII !0{} 3. asterisk !0{} 17. at !1{} 12. backslash !0{} 6. BACON !0{} 2. badness !0{} 20. baseline !0{} 11. batchmode !2{} 23. beauty !0{} 1. begingroup !2{} 15. Bemer, Robert, see TEX, ASCII !0{} 1. bf !2{} 10. bibliography !0{} 4. blank line !0{} 18. blank space !0{} 3. block structure !0{} 14. bold !0{} 10. brace !0{} 10. breaking a paragraph !0{} 21. c !2{} 17. carriage-return, see $\langle$return$\rangle$ !0{} 7. cedilla !0{} 18. centerline !2{} 14, 17, 23. chi !2{} 1, 2. cm fonts !0{} 12. cmr5 !1{} 12. column width !0{} 21. comments !0{} 19. Computer Modern !0{} 12. control sequences !0{} 6. control space !0{} 14. control symbol !0{} 6. control word !0{} 6. COWPER !0{} 25. curly brace !0{} 10. curly braces, see braces !0{} 14. dangerous bend !0{} 4, 11. dash !2{} 21. dashes !0{} 3. deleting tokens !0{} 22. design size !0{} 12. device independent !0{} 17. Dieter !0{} 10. discretionary hyphens !0{} 20. Drofnats !0{} 17. dvi !1{} 17. editing !0{} 24. eject !2{} 17, 18. El{\accent 18 e}ve !0{} 1. Em-dash !0{} 5. empty group !0{} 14. empty line !0{} 18. En-dash !0{} 2, 3. end !2{} 17, 19. endgroup !2{} 15. epsilon !2{} 1. errorcontextlines !2{} 24. error messages !0{} 21. errorstopmode !2{} 23. escape character !0{} 6. exercise !2{} 8. face !0{} 10. file names !0{} 18. font !2{} 12. fonts !0{} 10. format file !0{} 18. ge !2{} 7. global !2{} 15. grouping !0{} 10. grouping characters !0{} 14. HABAKKUK !0{} 25. hbadness !2{} 21. help messages !0{} 23. hfuzz !2{} 21. Honeywell Information Systems !0{} 1. HOWARD !0{} 16. hrule !2{} 17. hsize !2{} 19. hyphenation !0{} 20. hyphens !0{} 3. infty !2{} 7. input !2{} 6, 7, 18, 19. inserting text online !0{} 22. interacting with TeX !0{} 22. interrupt !0{} 23. it !2{} 10. italic correction !0{} 10. italic type !0{} 10. JEVONS !0{} 5. kern !2{} 8. kerning !0{} 4. lbrace rbrace !0{} 14. le !2{} 7. leading, see vskip !0{} 17. LEE !0{} 13. letter !0{} 6. ligature !0{} 14. ligatures !0{} 3, 4. LINCOLN !0{} 9. local !0{} 14. log file !0{} 8, 20. logo !0{} 1, 7. lowercase !0{} 7. lq !2{} 4. magnification !0{} 12. magnification !2{} 12. magstep !2{} 12. magstephalf !2{} 12. markup commands, see control sequences !0{} 6. measure, see hsize !0{} 21. minus signs !0{} 3. MUIRHEAD !0{} 16. ne !2{} 7. nested !0{} 14. nested groups !0{} 15. ninepoint !2{} 11. ninerm !2{} 11. ninesl !2{} 11. nonstopmode !2{} 23. nullfont !2{} 11. oblique !0{} 10. online interaction, see interaction !0{} 22. oplus !2{} 7. otimes !2{} 7. Output routines !0{} 15. overfull box !0{} 19. page number !0{} 15. paragraphs !0{} 18. percent !0{} 19. Pi !2{} 7. pi !2{} 7. piano !0{} 12. PLATO !0{} 2. points !0{} 11. Polya !0{} 6. preloaded formats !0{} 18. primitive !0{} 7. punctuation !0{} 11. quotation marks !0{} 3. quotes within quotes !0{} 4. raggedright !2{} 21. reduction !0{} 12. relax !2{} 17. r{\accent 19 e}sum{\accent 19 e}{} !0{} 253. return !3{} 17. \ !2{} 7. rm !2{} 10. roman type !0{} 10. rq !2{} 4. rule !0{} 18. Running the program !0{} 17. scrollmode !2{} 23. SELDEN !0{} 9. SHAKESPEARE !0{} 13. show !2{} 8. sl !2{} 10. Slanted type !0{} 10. space !0{} 6, 14. story.{}tex !1{} 17. subscripts !0{} 11. SWIFT !0{} 5. Szego !0{} 6. !2{} 7. tau !2{} 1. tenpoint !2{} 11. tenrm !2{} 11. tensl !2{} 11. TEX !0{} 1. TeX !1{} 1. TeX !2{} 7, 14. texput !1{} 17. thinspace !2{} 4, 8. Thor !0{} 17. ties !0{} 18. tilde !0{} 18. tolerance !2{} 21. transcript !0{} 20. tt !2{} 10. typeface !0{} 10. typewriter type !0{} 10. umlaut !0{} 6, 18. underfull box !0{} 21. uppercase !0{} 7. vfill !2{} 17, 18. vskip !2{} 17. \newcol \head{Appendix C: The index macros} Macros from blue.fmt (and manmac) are needed. Those have not been included. \thisverbatim{\numvrb \catcode`\<=12 \catcode`\!=12 \catcode`\|=12 \catcode`\;=0 \beginverbatim %From BLUe's Index Oct 94%;numvrb %Some unused macros are left in. \newread\inxin \newtoks\indword \newtoks\indexfile %To parameterize the resulting index \newtoks\irfile %To parameterize the IRs \newtoks\indexname \newtoks\preindex \newtoks\postindex \newtoks\conseqs \newtoks\consyms \newtoks\srtkeys \newtoks\srtkeypairs \newtoks\ignores %Initializations \proofmodetrue \irfile{index} \indexfile{index.elm} \indexname{Index} \preindex{\head{\the\indexname}} \postindex{} \immediate\openout\inx=index \conseqs{\c\space\bf\it\rm\tt \sub\relax} \consyms{\`\'\"\^\~} \srtkeypairs{\TeX{tex} \LaTeX{latex} \AmSTeX{amstex}} \srtkeys{\TeX\LaTeX\AmSTeX} \let\sub\relax %Macros %User level %;vrblin=100 \def\sortindex{%Nov 1994, cgl %Purpose: %To sort IR file. %Input: default index is sorted % ( file specified in \irfile) %Output: file index.elm. \newpage\immediate\closeout\inx \filetoarray{\the\irfile} \immediate\write16{Sorting n=\the\n. Please wait, O(nlog n) process.} \let\cmp\cmpir\let\nxtw\nxtwindex \otindex\let\ \space {%Make sortkey defs \ea\sokdef\the\skpairs\fedkos\relax \sort {\let\spaceseparator\space \setupnxtokens\def\ {\nx\ }% \immediate\write16{Range reduction.} \redrngtofile{index.srt} \immediate\write16{After reduction and writing to file index.srt; n=\the\n.} \immediate\write16{Transform index.srt-->index.elm.} \tawfiletofile{index.srt}{\the \indexfile}}} %Set up set of \srtkeys \def\setupsrtkeys{\ea \sok\the\srtkeypairs\kos\relax} %;vrblin=150 \def\pasteupindex{%Nov 1994, cgl %Purpose: %To set index in (balanced) doublecolumn. %The index is preceded by contents of %\preindex and followed by contents of %\postindex. %Input: default index.elm is set % (file specified in \indexfile). %Biased by manmac's \begindoublecolumns \newpage \begingroup \def\space{{\tt\char32 }}% \the\preindex\par \pageheight\vsize \pagewidth\pagewd%anachronism \parindent1em \output={\global\setbox\partialpage= \vbox{\unvbox255\bigskip}}% \eject \output={\bluedoublecolumnout}% \hsize=8.5cm \vsize=51cm%blue.fmt values \parskip0pt plus.8pt\relax \obeylines\everypar{% \hangindent2\parindent}% \let\par\endgraf \let\sub\endgraf \input\the\indexfile\relax %endpasteupindex part biased by %manmac's \enddoublecolumns \output={\balancecolumns}\eject \endgroup \pagegoal=\vsize\the\postindex} %Add an element #1 to toks var #2 \def\add#1to#2{#2\ea{\the#2#1}} %Inner level %IR creation %;vrblin=200 \def\makexref{\ifproofmode%Mod cgl oct 94 \bgroup\def\ {\string\ }% \def\process##1{\def##1{\string##1 }}% \ea\ea\ea\fifo\ea\the\ea\conseqs \the\srtkeys\ofif \def\process##1{\def##1{\string##1}}% \ea\fifo\the\consyms\ofif \xdef\writeit{\write\inx{\text{} !\xreftype\spaceseparator \nx\number\pageno.}}\writeit \egroup \else\ifhmode\kern0pt\fi\fi \ifsilent\ignorespaces\else{\next}\fi %Sorting %;vrblin=250 \def\cmpir#1#2{%#1, #2 defs %Result: \status= 0, 1, 2 if % \val{#1} =, >, < \val{#2} %\immediate\write16{Compared are: *#1* % and *#2*}% \ea\ea\ea\decom\ea#1#2} \def\nxtwindex#1#2{% %Function: %On input: #1 contains the `word' %As result: #2 contains the value % of the first non-ignored token as given % in the ordering table. %#1 contains the rest of the `word' \def\pop##1##2\pop{% \gdef#1{##2}\def\pophead{##1}}%head and tail \ea\pop#1\pop%split in head and tail \ignores\ea\ea\ea{\ea \the\ea\conseqs\the\consyms}% \ea\loc\pophead{\the\ignores}% \iffound\ifx\empty#1 \chardef#2=0 \else\nxtwindex#1#2 \fi \else \ea\loc\pophead{\the\srtkeys}% \iffound\xdef\pophead{\pophead}% \ea\ea\ea\gdef\ea\ea\ea#1\ea\ea\ea {\ea\pophead#1}% \nxtwindex#1#2 \else \ea\let\ea#2\csname ot\pophead\endcsname \fi \fi} \def\otindex{%Parameters: Ordering `table' %Special cases \ea\chardef\csname ot \endcsname=0 \ea\chardef\csname ot\space\endcsname=0 %{|}~(\char126) in ASCII after lowercase %^ active character %Bulk according to ACII \def\process##1{\ea\chardef \csname ot##1\endcsname=`##1 } %lowercase letters \fifo abcdefghijklmnopqrstuvwxyz\ofif \chardef\otij=`y \chardef\otIJ=`y %other characters \fifo !"##$&'()*+,-./0123456789:;<=>?@ []_`\ofif %uppercase letters equal lowercase \def\process##1{\ea\chardef \csname ot##1\endcsname=\lccode`##1 } \uppercase{\fifo abcdefghijklmnopqrstuvwxyz\ofif} %Range reduction %;vrblin=400 \def\redrngtofile#1{%Reduction of \1,...,\n, %with range representation of page numbers \immediate\openout\inx=#1 {\k1\kk0 \ifnum\n>0 \ea\ea\ea\splitwn\csname\the\k\endcsname \let\refer\word \let\nrsrng\empty\prcrng\num\fi \loop\ifnum\k<\n\advance\k1 \ea\ea\ea\splitwn\csname\the\k\endcsname \ifx\refer\word%extend \nrsrng with number \prcrng\num \else%write record to \kk \advance\kk1 \strnrs \immediate\write\inx{\refer\spaceseparator \nrsrng.}% \let\nrsrng\empty\init\num \prcrng\num\let\refer\word \fi \repeat\ifnum1<\n \advance\kk1 \strnrs \immediate\write\inx{\refer\spaceseparator \nrsrng.}% \global\n\kk\fi }\immediate\closeout\inx} %Copying %;vrblin=500 \def\filetoarray#1{%#1 is file name \immediate\openin\inxin=#1\relax \ifeof\inxin\immediate\write16{File #1 empty or non-existent.}% \fi \n\kzero\continuetrue \loop\ifeof\inxin\continuefalse\fi \ifcontinue\advance\n1 \immediate \read\inxin t\ea o\csname\the\n\endcsname %\immediate\write16{k: \number\n: % \csname\the\n\endcsname}% \repeat\advance\n-1 \immediate\closein\inxin} \def\tawfiletofile#1#2{\continuetrue \immediate\openin\inxin=#1\relax \immediate\openout\inx=#2\relax \loop\read\inxin to\IR \ifeof\inxin\continuefalse\fi \ifcontinue\trfandwrite\IR \repeat \immediate\closein\inxin \immediate\closeout\inx \def\setupnxtokens{% \def\process##1{\def##1{\nx##1}}% \ea\ea\ea\fifo\ea\the\ea\conseqs \the\srtkeys\ofif \def\process##1{\def##1{\string##1}}% \ea\fifo\the\consyms\ofif \def\trfandwrite#1{\ea\splitintoks#1% \immediate\write\inx{\nx\noindent \ifcase\digit{\the\indword}\or {\nx\tt\the\indword}\or {\nx\tt\char92\hbox{\the\indword}}\or $\nx\langle\hbox{\the\indword}\nx\rangle $\fi\spaceseparator\pagenrs.}} \def\splitintoks#1 !#2 #3.{\indword{#1}% \chardef\digit=#2\relax\def\pagenrs{#3}} %Typesetting;vrblin=600 \def\bluedoublecolumnout{% %Biased by manmac's doublecolumnout \splittopskip=\topskip \splitmaxdepth=\maxdepth \dimen@=25cm \advance\dimen@ by-\ht\partialpage \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@ \blueonepageout\pagesofar \unvbox255 \penalty\outputpenalty} \def\blueonepageout#1{% %Biased by manmac's \onepageout \shipout\vbox{% \vbox to\baselineskip{\null \the\headline\vss}% \kern2ex \vbox to \pageheight{#1}% \kern1ex \the\footline }\advancepageno} %Auxiliaries %SetOfKeys;vrblin=700 \def\sok#1#2{%Function: %Build from \srtkeypairs \srtkeys %via \ea\sok\srtkeypairs\kos\relax \ifx#1\kos\kos\fi \srtkeys\ea{\the\srtkeys#1}\sok} \def\kos#1\sok{\fi} \def\sokdef#1#2{%Function: %Build from \skpairs srtkey defs \ifx#1\fedkos\fedkos\fi \def#1{#2}\sokdef} \def\fedkos#1\sokdef{\fi} %;nonum %Table of contents: blue.ind %Variables % \indexname................8, 19 % \preindex.................9, 20 % \postindex................10, 21 % \indword..................3 % \indexfile................4, 19 % \irfile...................6, 18 % \conseqs..................11, 24-25 % \consyms..................12, 26 % \srtkeys..................13, 30 % \srtkeypairs..............14, 28-29 % \ignores..................15 %User level macros % \sortindex................101-125 % \pasteupindex.............151-183 % \add#1to#2................186 % \setupsrtkeys.............127-129 %Lower level macros %IR Creation % \makexref.................201-214 %Sorting % \cmpir....................251-256 % \nxtwindex................258-282 % \otindex..................284-304 %Range reduction % \redrngtofile.............401-424 %Copying % \filetoarray..............501-512 % \tawfiletofile............514-523 % \trfandwrite..............533-539 % \steupnxtokens............525-531 % \splitintoks..............541-542 %OTR doublecolumns % \bluedoublecolumnout......601-609 % \blueonepageout...........611-620 %Auxiliaries % \sok......................701-705 % \sokdef...................706-711 %History of changes %Nov 1994 Set up. %end%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%index% ;endverbatim \endscript